﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;

namespace ProgramMain.Framework
{
    public partial class BaseDetailCtl : DevExpress.XtraEditors.XtraUserControl
    {
        public BaseDetailCtl()
        {
            InitializeComponent();
        }

        private Nullable<Int32> m_Detail_ID;
        /// <summary>
        /// Фильтр по объекту
        /// </summary>
        public Nullable<Int32> DetailID
        {
            get { return m_Detail_ID; }
            set
            {
                if (m_Detail_ID != value)
                {
                    DetailEventArgs e = new DetailEventArgs(m_Detail_ID, value);
                    m_Detail_ID = value;
                    OnDetailIDChanged(e);
                }
            }
        }

        private bool m_bEnableEdit = true;
        /// <summary>
        /// Разрешение редактирования тарифоного плана
        /// </summary>
        public bool EnableEdit
        {
            get { return m_bEnableEdit; }
            set
            {
                m_bEnableEdit = value;
                OnEnableEditingChanged(EventArgs.Empty);
            }
        }
        /// <summary>
        /// Событие, срабатывает на изменение фильтра по объекту
        /// </summary>
        public event EventHandler EnableEditingChanged;

        protected virtual void OnEnableEditingChanged(EventArgs e)
        {
            if (EnableEditingChanged != null)
                EnableEditingChanged(this, e);
        }

        /// <summary>
        /// Событие, срабатывает после изменение фильтра по объекту
        /// </summary>
        public event EventHandler<DetailEventArgs> DetailIDChanged;

        protected virtual void OnDetailIDChanged(DetailEventArgs e)
        {
            if (DetailIDChanged != null)
                DetailIDChanged(this, e);
        }

        public enum ShowDetailModes { Unspecified, ViewOnly, Edit };

        public class ShowDetailEventArgs
        {
            // Summary:
            //     Represents an event with no event data.
            public static readonly ShowDetailEventArgs Empty = new ShowDetailEventArgs();

            // Summary:
            //     Initializes a new instance of the System.EventArgs class.
            private ShowDetailEventArgs()
            {
            }

            public ShowDetailEventArgs(Nullable<Int32> valDetailID)
            {
                DetailID = valDetailID;
                ShowMode = ShowDetailModes.Unspecified;
            }

            public ShowDetailEventArgs(Nullable<Int32> valDetailID, Nullable<Int32> valDetailIDType)
            {
                DetailID = valDetailID;
                ShowMode = ShowDetailModes.Unspecified;
                DetailIDType = valDetailIDType;
            }

            public ShowDetailEventArgs(Nullable<Int32> valDetailID, ShowDetailModes valShowMode, string valCaption)
            {
                DetailID = valDetailID;
                ShowMode = valShowMode;
                Caption = valCaption;
            }

            public ShowDetailEventArgs(Nullable<Int32> valDetailID, ShowDetailModes valShowMode, string valCaption, Nullable<Int32> valDetailIDType)
            {
                DetailID = valDetailID;
                ShowMode = valShowMode;
                Caption = valCaption;
                DetailIDType = valDetailIDType;
            }

            public Nullable<Int32> DetailID = new Nullable<Int32>();
            public Nullable<Int32> DetailIDType = new Nullable<Int32>();
            public ShowDetailModes ShowMode = ShowDetailModes.Unspecified;
            public string Caption = "";
        }

        public delegate void ShowDetailEventHandler(object sender, ShowDetailEventArgs e);

        private void BaseDetailCtl_Load(object sender, EventArgs e)
        {
            BaseDetailCtl_OnLoadControlInternal(sender, e);
        }

        private bool m_bFormLoaded = false;
        private void BaseDetailCtl_OnLoadControlInternal(object sender, EventArgs e)
        {
            if (!m_bFormLoaded)
            {
                OnLoadControl(sender, e);
                m_bFormLoaded = true;
            }
        }

        virtual public void OnLoadControl(object sender, EventArgs e)
        {
        }

        private void FrmCommon_ParentChanged(object sender, EventArgs e)
        {
            if (this.ParentForm != null)
            {
                this.ParentForm.Load += new EventHandler(this.BaseDetailCtl_OnLoadControlInternal);
            }
            else
            {
                Form parent = this.FindForm();
                if (parent is Form)
                {
                    parent.Load += new EventHandler(this.BaseDetailCtl_OnLoadControlInternal);
                }
            }
        }

        virtual protected bool IsLoadDelayed()
        {
            return DetailID == null;
        }

        virtual protected void LoadData()
        {
        }

        virtual protected void UpdateData()
        {
        }

        virtual protected void RollbackData()
        {
        }

        protected void RoolbackDataTable(DataTable dataTable)
        {
            dataTable.RejectChanges();
        }

        public void DBRead()
        {
            RefreshData(false);
        }

        public void DBWrite()
        {
            RefreshData(true);
        }

        protected void ShowWaiting()
        {
            if (IsLoadDelayed())
            {
                Framework.frmWaiting.ShowWaiting();
            }
        }

        protected void HideWaiting()
        {
            Framework.frmWaiting.HideWaiting();
        }

        private void RefreshData(bool bUpdate)
        {
            try
            {
                try
                {
                    if (bUpdate || IsLoadDelayed())
                    {
                        ShowWaiting();
                    }
                    if (bUpdate == false)
                    {
                        LoadData();
                    }
                    else
                    {
                        UpdateData();
                    }
                }
                catch (Exception e)
                { ShowWriteError(e); }
                finally
                {
                    HideWaiting();
                }
            }
            catch (Exception e)
            {
                if (bUpdate == false)
                {
                    ShowReadError(e);
                }
                else
                {
                    RollbackData();
                    ShowWriteError(e);
                }
            }
        }

        public void ShowReadError(Exception e)
        {
            XtraMessageBox.Show(e.Message, "Непредвиденная ошибка во время чтения данных!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        public void ShowWriteError(Exception e)
        {
            XtraMessageBox.Show(e.Message, "Непредвиденная ошибка во время записи данных!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        virtual public BaseSecurity.SuperBool CheckSecurityAction(BaseSecurity.SecurityActionType ActionType, bool ShowWarning)
        {
            BaseSecurity.SuperBool res = BaseSecurity.CheckSecurityAction(ActionType);

            BaseSecurity.ShowSecurityWarning(ShowWarning, res);

            return res;
        }

        public bool CheckSecurityViewAction()
        {
            return CheckSecurityAction(BaseSecurity.SecurityActionType.View, true) != BaseSecurity.SuperBool.False;
        }

        public bool CheckSecurityEditAction()
        {
            return CheckSecurityEditAction(true);
        }
        public bool CheckSecurityEditAction(bool ShowWarning)
        {
            return CheckSecurityAction(BaseSecurity.SecurityActionType.Edit, ShowWarning) != BaseSecurity.SuperBool.False;
        }

        public bool CheckSecurityDeleteAction()
        {
            return CheckSecurityAction(BaseSecurity.SecurityActionType.Delete, true) != BaseSecurity.SuperBool.False;
        }

        public bool CheckSecuritySuperAction()
        {
            return CheckSecuritySuperAction(true);
        }
        public bool CheckSecuritySuperAction(bool ShowWarning)
        {
            return CheckSecurityAction(BaseSecurity.SecurityActionType.Edit, ShowWarning) == BaseSecurity.SuperBool.Super;
        }
    }
}
